<html>
<head><meta charset="utf-8"><title>Box&#x27;s Memory layout for ZSTs · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html">Box&#x27;s Memory layout for ZSTs</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="208276910"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208276910" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208276910">(Aug 27 2020 at 21:11)</a>:</h4>
<p>Hi,<br>
Box documents nicely its memory layout and which pointers can you pass for deallocation to it. (<a href="https://doc.rust-lang.org/std/boxed/index.html#memory-layout">https://doc.rust-lang.org/std/boxed/index.html#memory-layout</a>)<br>
it does not specify the memory layout for ZSTs and which pointers can I pass to it.<br>
Specifically I'm interested in things like:</p>
<div class="codehilite"><pre><span></span><code>Box::from_raw(&amp;mut [0u8; 0] as *mut [u8] );
Box::from_raw(&amp;[0u8; 0] as *const [u8] as *mut [u8] );
Box::from_raw((NonNull::&lt;[u8;0]&gt;::dangling() as NonNull&lt;[u8]&gt;).as_ptr());
</code></pre></div>


<p>(obv all ZSTs are interesting but these apply to some concerns I have)</p>



<a name="208278597"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208278597" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208278597">(Aug 27 2020 at 21:25)</a>:</h4>
<p>I think it should be something like:</p>
<blockquote>
<p>For zero-sized-types the pointer must be non-null and aligned for the type. </p>
</blockquote>
<p>And maybe even be explicit and say that:</p>
<blockquote>
<p>You can obtain a pointer that is usable as data for zero-sized type using NonNull::dangling().</p>
</blockquote>
<p>But maybe I'm wrong?</p>



<a name="208285770"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208285770" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208285770">(Aug 27 2020 at 22:48)</a>:</h4>
<p>The last would allow you to fabricate a value of any ZST, e.g. by <code>let v: SomeZst = *Box::from_raw(NonNull::&lt;SomeZst&gt;::dangling());</code>. I've seen plenty of code that uses ZSTs as tokens that "prove" some initialization has taken place. The others could allow duplication of non-copy ZST values which is probably bad too. (No clue if the particulars of using it as a slice is okay, though)</p>



<a name="208288851"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208288851" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208288851">(Aug 27 2020 at 23:32)</a>:</h4>
<p>Oh you mean that the problem is that the Drop impl will be called and might invalidate some library invariant?</p>



<a name="208292835"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208292835" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208292835">(Aug 28 2020 at 00:37)</a>:</h4>
<p>yeah if you drop a "proof" zst that was fake, bad things can happen</p>



<a name="208310613"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208310613" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matt1992 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208310613">(Aug 28 2020 at 06:46)</a>:</h4>
<p>I use some ZST structs with private constructors as arguments to <code>const fn</code>, to prove that a trait has been implemented, some of those traits are unsafe.</p>



<a name="208310696"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208310696" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matt1992 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208310696">(Aug 28 2020 at 06:48)</a>:</h4>
<p>I do that because there's no way to write trait bounds in <code>const fn</code>s in stable Rust.</p>



<a name="208311261"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208311261" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matt1992 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208311261">(Aug 28 2020 at 06:59)</a>:</h4>
<p>I would consider it fine to <code>mem::forget(zst)</code> then construct a <code>Box&lt;ThatZstType&gt;</code> with a dummy pointer.<br>
The issue is constructing one from nowhere.</p>



<a name="208317150"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208317150" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208317150">(Aug 28 2020 at 08:30)</a>:</h4>
<p>Somewhat related: <a href="https://github.com/rust-lang/rust-memory-model/issues/44#issuecomment-355139160">https://github.com/rust-lang/rust-memory-model/issues/44#issuecomment-355139160</a></p>
<p>So it's _valid_ but not necessarily _safe_ to summon ZSTs from the æther.</p>



<a name="208322166"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208322166" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208322166">(Aug 28 2020 at 09:31)</a>:</h4>
<p>I'm not sure this is relevant to my question though.</p>
<p>It is safe to allocate any ZST and to then deallocate, if that ZST has some library invariants it's your job to handle them. This is true for all types, not just ZST.<br>
The question is about the memory model of Box/GlobalAlloc, and what is UB and what is not.<br>
Not about if you should be careful when manually allocating foreign types.</p>



<a name="208365139"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208365139" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208365139">(Aug 28 2020 at 16:29)</a>:</h4>
<p><span class="user-mention" data-user-id="249222">@Elichai Turkel</span> I agree. When we document the layout of ZST <code>Box</code> that doesn't mean it becomes <em>safe</em> to just construct a <code>Box</code> for any ZST with that recipe. However, it might be worth mentioning this explicitly.</p>



<a name="208365292"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208365292" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208365292">(Aug 28 2020 at 16:30)</a>:</h4>
<p>regarding the actual invariant... you'd think it is just "non-null and aligned", but I think it is more tricky. specifically, I think the following is UB:</p>
<div class="codehilite"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">b</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="mi">0</span><span class="k">i32</span><span class="p">);</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">ptr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="o">*</span><span class="n">b</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="kt">i32</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">();</span><span class="w"></span>
<span class="nb">drop</span><span class="p">(</span><span class="n">b</span><span class="p">);</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">zst_box</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">from_raw</span><span class="p">(</span><span class="n">ptr</span><span class="p">);</span><span class="w"></span>
</code></pre></div>



<a name="208365386"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208365386" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208365386">(Aug 28 2020 at 16:31)</a>:</h4>
<p>the problem is that <code>zst_box</code> is a dangling pointer, and LLVM knows it. Doing <code>getelementptr inbounds</code> on such pointers most likely is UB. (I was not able to get LLVM devs to commit otherwise, in a long mailing list discussion. I am not sure most of them even understood what I was going on about...)</p>



<a name="208365533"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208365533" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208365533">(Aug 28 2020 at 16:32)</a>:</h4>
<p>so how is <code>align_of::&lt;ZST&gt;() as *const ZST</code> is not a dangling pointer in the same sense?</p>



<a name="208365556"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208365556" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208365556">(Aug 28 2020 at 16:32)</a>:</h4>
<p>I just realized <a href="https://doc.rust-lang.org/nightly/core/ptr/index.html">https://doc.rust-lang.org/nightly/core/ptr/index.html</a> also gets this wrong, I think :/</p>



<a name="208365592"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208365592" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208365592">(Aug 28 2020 at 16:33)</a>:</h4>
<p><span class="user-mention" data-user-id="249222">@Elichai Turkel</span> there's a big difference between a ptr cast from integer, and a ptr obtaiend via <code>malloc</code></p>



<a name="208365599"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208365599" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208365599">(Aug 28 2020 at 16:33)</a>:</h4>
<p>it's related to ptr provenance</p>



<a name="208365647"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208365647" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208365647">(Aug 28 2020 at 16:33)</a>:</h4>
<p>FYI <a href="https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety">https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety</a></p>



<a name="208365700"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208365700" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208365700">(Aug 28 2020 at 16:34)</a>:</h4>
<p><code>align_of::&lt;ZST&gt;() as *const ZST</code> is a ptr that, as far as LLVM is concerned, <em>might</em> dangle. or not.<br>
<code>zst_box</code> above <em>definitely</em> dangles.</p>



<a name="208365735"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208365735" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208365735">(Aug 28 2020 at 16:34)</a>:</h4>
<p>yes. we'll have to adjust "valid for 0 bytes" to take this into account.</p>



<a name="208365962"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208365962" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208365962">(Aug 28 2020 at 16:36)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208365592">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="249222">Elichai Turkel</span> there's a big difference between a ptr cast from integer, and a ptr obtaiend via <code>malloc</code></p>
</blockquote>
<p>So we're back in a pointer provenance situation here?</p>



<a name="208366001"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208366001" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208366001">(Aug 28 2020 at 16:36)</a>:</h4>
<p>we're always in a ptr provenance situation when talking about pointers :(</p>



<a name="208366282"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208366282" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208366282">(Aug 28 2020 at 16:39)</a>:</h4>
<p>At least other languages are also having trouble with this <a href="https://play.golang.org/p/g4cjteaaUeQ">https://play.golang.org/p/g4cjteaaUeQ</a> <span aria-label="sweat smile" class="emoji emoji-1f605" role="img" title="sweat smile">:sweat_smile:</span></p>



<a name="208366646"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208366646" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208366646">(Aug 28 2020 at 16:42)</a>:</h4>
<p>it's a hard problem^^</p>



<a name="208366686"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208366686" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208366686">(Aug 28 2020 at 16:42)</a>:</h4>
<p>and more troublesome many people haven't yet realized that there even is a problem...</p>



<a name="208366799"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208366799" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> HeroicKatora <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208366799">(Aug 28 2020 at 16:43)</a>:</h4>
<p>Wait a minute, in go you can observe the provenance information at runtime by using <code>==</code> but not by inspecting the pointer? That's .. uh .. I'll need an explanation.</p>



<a name="208366825"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208366825" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208366825">(Aug 28 2020 at 16:44)</a>:</h4>
<p>so I think what we can and should do here is:</p>
<ul>
<li>adjust the docs for "valid ptr" to say that even for ZSTs, they may not point to <em>deallocated</em> memory. they are however allowed to point to a fixed (non-0) integer -- memory that conceivably could actually exist.</li>
<li>for <code>Box</code>, document that the memory needs to be aligned and valid. then the above clause kicks in.</li>
</ul>



<a name="208366917"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208366917" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208366917">(Aug 28 2020 at 16:44)</a>:</h4>
<p><span class="user-mention silent" data-user-id="229913">HeroicKatora</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208366799">said</a>:</p>
<blockquote>
<p>Wait a minute, in go you can observe the provenance information at runtime by using <code>==</code> but not by inspecting the pointer? That's .. uh .. I'll need an explanation.</p>
</blockquote>
<p>I dont knowmuch about go, but in LLVM what you are actually observing is non-determinism</p>



<a name="208366960"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208366960" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208366960">(Aug 28 2020 at 16:44)</a>:</h4>
<p>provenance is nit observable in LLVM, <code>==</code> ignores provenance -- that's the claim, anyway. And so far the LLVM devs treat it as a bug when we find counterexamples.^^</p>



<a name="208367018"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208367018" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208367018">(Aug 28 2020 at 16:45)</a>:</h4>
<p>but we still can have effects like that example <span class="user-mention" data-user-id="249222">@Elichai Turkel</span> posted because of non-determinism, and because different optimization choices can restrict non-determinism in different ways.</p>



<a name="208367159"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208367159" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> HeroicKatora <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208367159">(Aug 28 2020 at 16:46)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208366917">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="229913">HeroicKatora</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208366799">said</a>:</p>
<blockquote>
<p>Wait a minute, in go you can observe the provenance information at runtime by using <code>==</code> but not by inspecting the pointer? That's .. uh .. I'll need an explanation.</p>
</blockquote>
<p>I dont knowmuch about go, but in LLVM what you are actually observing is non-determinism</p>
</blockquote>
<p>Ah, I see. They don't use any particular dangling pointer as rust currently does for known zst slices allocation. E.g. the default impl for <code>&amp;_ [T]</code>.</p>



<a name="208367383"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208367383" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208367383">(Aug 28 2020 at 16:48)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> wait. "memory that conceivably could actually exist" is debatable. I've heard people say that "ZSTs in rust sometimes have invalid pointers because it's in the null page"</p>



<a name="208367467"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208367467" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208367467">(Aug 28 2020 at 16:48)</a>:</h4>
<p>the null page is not part of the rust spec</p>



<a name="208367484"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208367484" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208367484">(Aug 28 2020 at 16:49)</a>:</h4>
<p>just specifically the NULL ptr is</p>



<a name="208367516"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208367516" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208367516">(Aug 28 2020 at 16:49)</a>:</h4>
<p>it is the only fixed integer address that rust assumes to definitely not exist</p>



<a name="208367642"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208367642" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208367642">(Aug 28 2020 at 16:50)</a>:</h4>
<p>(the very last address of the address space also cannot be allocated as if it was, computing the 1-past-the-end ptr would overflow. but unlike NULL, the very last address <em>can</em> be 1-past-the-end of another allocation.)</p>



<a name="208367644"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208367644" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208367644">(Aug 28 2020 at 16:50)</a>:</h4>
<p>I guess that's a fair answer. Rust doesn't care how computers are implemented in practice, it can theoretically compile down to different memory addresses(I think?)</p>



<a name="208367692"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208367692" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208367692">(Aug 28 2020 at 16:50)</a>:</h4>
<p><span class="user-mention silent" data-user-id="249222">Elichai Turkel</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208367644">said</a>:</p>
<blockquote>
<p>I guess that's a fair answer. Rust doesn't care how computers are implemented in practice, it can theoretically compile down to different memory addresses(I think?)</p>
</blockquote>
<p>I mean whenever I say "we dont care how computers work" someone reminds me that rust programs run on real computers ;) but in principle, yes.</p>



<a name="208367712"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208367712" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208367712">(Aug 28 2020 at 16:50)</a>:</h4>
<p>real computers inform the spec, but once we have a spec, only the spec matters.</p>



<a name="208368048"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208368048" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208368048">(Aug 28 2020 at 16:53)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208367692">said</a>:</p>
<blockquote>
<p>I mean whenever I say "we dont care how computers work" someone reminds me that rust programs run on real computers ;) but in principle, yes.</p>
</blockquote>
<p>lol, yeah, my point is that theoretically we can say that whenever you see in rust a pointer at address 100 in the machine it will be 200, and rust will convert it whenever you try to observe the pointer(not sure if this is valid, and it is way off the subject anyway)</p>



<a name="208368296"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208368296" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208368296">(Aug 28 2020 at 16:55)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208366825">said</a>:</p>
<blockquote>
<p>so I think what we can and should do here is:</p>
<ul>
<li>adjust the docs for "valid ptr" to say that even for ZSTs, they may not point to <em>deallocated</em> memory. they are however allowed to point to a fixed (non-0) integer -- memory that conceivably could actually exist.</li>
<li>for <code>Box</code>, document that the memory needs to be aligned and valid. then the above clause kicks in.</li>
</ul>
</blockquote>
<p>I like that :) also maybe the <code>Box</code> documentation should link to the pointer docs</p>



<a name="208368817"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208368817" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208368817">(Aug 28 2020 at 16:59)</a>:</h4>
<p>Is <code>may not point to deallocated memory</code> enough? or should it say something like <code>may not point to memory obtained from a different object allocated or deallocated</code></p>



<a name="208368954"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208368954" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208368954">(Aug 28 2020 at 17:00)</a>:</h4>
<blockquote>
<p>lol, yeah, my point is that theoretically we can say that whenever you see in rust a pointer at address 100 in the machine it will be 200, and rust will convert it whenever you try to observe the pointer(not sure if this is valid, and it is way off the subject anyway)</p>
</blockquote>
<p>if we can actually make every other part of the spec work -- then yes. but given tht rust has ptr-int casts and bytewise accesses, I doubt this can actually be done.</p>



<a name="208369003"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208369003" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208369003">(Aug 28 2020 at 17:00)</a>:</h4>
<p><span class="user-mention silent" data-user-id="249222">Elichai Turkel</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208368817">said</a>:</p>
<blockquote>
<p>Is <code>may not point to deallocated memory</code> enough? or should it say something like <code>may not point to memory obtained from a different object allocated or deallocated</code></p>
</blockquote>
<p>I dont know what the second variant means.</p>



<a name="208369271"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208369271" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208369271">(Aug 28 2020 at 17:02)</a>:</h4>
<p>it means that this is also not allowed: even though it is not deallocated</p>
<div class="codehilite"><pre><span></span><code>let mut a = 5i32;
let b = &amp;mut a as *mut i32 as *mut ();
let zst_box = Box::from_Raw(b);
</code></pre></div>



<a name="208369387"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208369387" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208369387">(Aug 28 2020 at 17:03)</a>:</h4>
<p>no that code is fine</p>



<a name="208369414"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208369414" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208369414">(Aug 28 2020 at 17:03)</a>:</h4>
<p>"different object" in your def.n begs the question "different from what"</p>



<a name="208369449"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208369449" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208369449">(Aug 28 2020 at 17:03)</a>:</h4>
<p>it's okay for a ZST box to point to some actually existing memory. just when that memory is deallocated, the box becomes invalid.</p>



<a name="208370286"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208370286" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208370286">(Aug 28 2020 at 17:11)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208369449">said</a>:</p>
<blockquote>
<p>it's okay for a ZST box to point to some actually existing memory. just when that memory is deallocated, the box becomes invalid.</p>
</blockquote>
<p>omg lol, that's crazier than I'd thought</p>



<a name="208371781"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208371781" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208371781">(Aug 28 2020 at 17:24)</a>:</h4>
<p>how's that crazier? it's just a consequence of what I said earlier I think?</p>



<a name="208374801"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208374801" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208374801">(Aug 28 2020 at 17:50)</a>:</h4>
<p>it is exactly what you said, I just tried to apply some (apparently invalid) logic here (that the problem is that it is a different object etc, not <em>just</em> that it was deallocated)<br>
is the deallocation true also for stack deallocation?</p>



<a name="208376044"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208376044" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208376044">(Aug 28 2020 at 18:01)</a>:</h4>
<p>yes</p>



<a name="208376059"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208376059" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208376059">(Aug 28 2020 at 18:01)</a>:</h4>
<p>on the spec level, there is not much of a difference between stack and heap allocations</p>



<a name="208376112"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208376112" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208376112">(Aug 28 2020 at 18:02)</a>:</h4>
<p>basically the only difference is that if you try to <code>free</code> a stack allocation, that's UB ;)</p>



<a name="208376151"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208376151" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208376151">(Aug 28 2020 at 18:02)</a>:</h4>
<p>also, "stack allocation" here means "individual stack-allocated variable". there is no such thing as a stack frame.</p>



<a name="208386408"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208386408" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208386408">(Aug 28 2020 at 19:36)</a>:</h4>
<p>Whaat? This spec sounds crazy. Why should "potentially deallocated memory" be okay but "definitely deallocated memory" is not? Besides the fact that LLVM may not be smart enough to rough up the code in one case, from a spec perspective that shouldn't matter</p>



<a name="208386829"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208386829" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208386829">(Aug 28 2020 at 19:40)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208365292">said</a>:</p>
<blockquote>
<p>regarding the actual invariant... you'd think it is just "non-null and aligned", but I think it is more tricky. specifically, I think the following is UB:</p>
<div class="codehilite"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">b</span><span class="w">  </span><span class="o">=</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="mi">0</span><span class="k">i32</span><span class="p">);</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">ptr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="o">*</span><span class="n">b</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="kt">i32</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">();</span><span class="w"></span>
<span class="nb">drop</span><span class="p">(</span><span class="n">b</span><span class="p">);</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">zst_box</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">from_raw</span><span class="p">(</span><span class="n">ptr</span><span class="p">);</span><span class="w"></span>
</code></pre></div>


<p>the problem is that <code>zst_box</code> is a dangling pointer, and LLVM knows it. Doing <code>getelementptr inbounds</code> on such pointers most likely is UB. (I was not able to get LLVM devs to commit otherwise, in a long mailing list discussion. I am not sure most of them even understood what I was going on about...)</p>
</blockquote>
<p>This sounds like an LLVM problem, not a rust problem. I don't see how you could ever <code>getelementptr inbounds</code> on a ZST pointer except with offset 0, and it should be easy enough to make that defined to equal the input</p>



<a name="208387331"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208387331" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208387331">(Aug 28 2020 at 19:45)</a>:</h4>
<p>Here's a thought: model ZST pointers as the same as integers (i.e. with the same provenance as what you would get by casting a pointer to an integer). They can't actually be dereferenced, or really anything else except casting to other types (since offsetting does nothing), so a simple integer model should be possible</p>



<a name="208397730"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208397730" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208397730">(Aug 28 2020 at 21:37)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208386408">said</a>:</p>
<blockquote>
<p>Whaat? This spec sounds crazy. Why should "potentially deallocated memory" be okay but "definitely deallocated memory" is not? Besides the fact that LLVM may not be smart enough to rough up the code in one case, from a spec perspective that shouldn't matter</p>
</blockquote>
<p>There is a difference between a deallocated allocation and sonething that was never an allocation at all, but instead a plain integer.</p>



<a name="208398121"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208398121" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208398121">(Aug 28 2020 at 21:42)</a>:</h4>
<p>I know, but I don't think that difference should matter for validity of ZST pointers</p>



<a name="208398347"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208398347" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208398347">(Aug 28 2020 at 21:45)</a>:</h4>
<p>While I can imagine that some rusty semantics can be placed on ZST pointers enforcing some lifetime rules (actually... stacked borrows uses per memory location tracking so this might be a problem... setting that aside), at the LLVM level, because malloc does not allow zero size calls, it's not really possible to get ZST types to live in a real allocation in the first place. So unless they are being used to smuggle a different pointer type, in which case you can use the same pointer provenance rules as ptr-to-int casts, they should have no relation with memory at all. In short, a ZST pointer is just an (aligned nonzero) int.</p>



<a name="208399072"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208399072" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208399072">(Aug 28 2020 at 21:55)</a>:</h4>
<p>For example, it is impossible to construct a valid <code>*const [(u8, Void); 0]</code> in the sense of pointing to somewhere between the beginning and one past the end of an allocation, because all <em>nonzero</em> allocations of the type are invalid, so there is no valid <code>malloc</code> call that could be used to derive such a pointer. For this to make any sense "dangling" pointers to the type have to be valid. (Not to mention the obvious, that <code>NonNull::dangling()</code> is the officially correct way to construct ZST pointers so the spec is constrained to make this valid).</p>



<a name="208426051"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208426051" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208426051">(Aug 29 2020 at 09:44)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> </p>
<blockquote>
<p>This sounds like an LLVM problem, not a rust problem. I don't see how you could ever getelementptr inbounds on a ZST pointer except with offset 0, and it should be easy enough to make that defined to equal the input</p>
</blockquote>
<p>should be easy, yes. if you'd like to work on putting that into the LLVM langref, I would be delighted. :) I tried to do that by starting a mailing list discussion, which went nowhere. Maybe there is a better approach. The thing is, I have no idea if there are LLVM optimizations that rely on <code>GEP inbounds</code>-by-0 being UB for dangling pointers.<br>
but with the status quo, we have to work with what we are given, I am afraid.</p>



<a name="208426103"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208426103" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208426103">(Aug 29 2020 at 09:46)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208387331">said</a>:</p>
<blockquote>
<p>Here's a thought: model ZST pointers as the same as integers (i.e. with the same provenance as what you would get by casting a pointer to an integer). They can't actually be dereferenced, or really anything else except casting to other types (since offsetting does nothing), so a simple integer model should be possible</p>
</blockquote>
<p>nono that would be an awful lot of complexity. having pointers with provenance cast to and from integers without is bad enough. <em>everything</em> based on provenance would suddenly have to rely on an analysis "is this a ZST ptr or not" (and with dynamically sized types or polymorphic MIR code you might not even know).</p>



<a name="208426113"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208426113" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208426113">(Aug 29 2020 at 09:46)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208398121">said</a>:</p>
<blockquote>
<p>I know, but I don't think that difference should matter for validity of ZST pointers</p>
</blockquote>
<p>I agree. I described reality as it is, not as it should be. ;)</p>



<a name="208426173"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208426173" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208426173">(Aug 29 2020 at 09:48)</a>:</h4>
<blockquote>
<p>While I can imagine that some rusty semantics can be placed on ZST pointers enforcing some lifetime rules (actually... stacked borrows uses per memory location tracking so this might be a problem... setting that aside)</p>
</blockquote>
<p>stacked borrows works on the locations affected by doing things with a pointer. ZST references/pointers affect no memory, so stacked borrows doesn't care.</p>



<a name="208426174"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208426174" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208426174">(Aug 29 2020 at 09:48)</a>:</h4>
<blockquote>
<p>For example, it is impossible to construct a valid *const [(u8, Void); 0] in the sense of pointing to somewhere between the beginning and one past the end of an allocation</p>
</blockquote>
<p>that's not true. just construct a pointer to <code>([Void; 0], i32)</code>.</p>



<a name="208426245"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208426245" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208426245">(Aug 29 2020 at 09:50)</a>:</h4>
<p>re: LLVM, there is also the option of adjusting rustc codegen to guarantee that we never go <code>GEP inbounds</code> for ZST. I am not sure if that is realistic. it would be a hack to work around an LLVM problem.</p>



<a name="208426256"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208426256" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208426256">(Aug 29 2020 at 09:51)</a>:</h4>
<p>(Cc <span class="user-group-mention" data-user-group-id="1176">@WG-llvm</span> maybe some of you can help here -- <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208426051">this comment</a> summarizes the problem quite well.)</p>



<a name="208437590"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208437590" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208437590">(Aug 29 2020 at 14:53)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> LLVM has to consider pointers that come out of thin air (i.e. <code>intptrcast</code>ed from some arbitrary non-zero integer) "valid", so "dangling" is not a problem I believe, and so <code>GEPi (inttoptr $align)</code> should also be fine.</p>



<a name="208437596"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208437596" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208437596">(Aug 29 2020 at 14:53)</a>:</h4>
<p>in particular <a href="https://llvm.org/docs/LangRef.html#pointer-aliasing-rules">https://llvm.org/docs/LangRef.html#pointer-aliasing-rules</a> says this (I can’t find anything more concrete, but I remember this being the case for some reason)</p>
<blockquote>
<p>An integer constant other than zero or a pointer value returned from a function not defined within LLVM may be associated with address ranges allocated through mechanisms other than those provided by LLVM. Such ranges shall not overlap with any ranges of addresses allocated by mechanisms provided by LLVM.</p>
</blockquote>



<a name="208437674"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208437674" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208437674">(Aug 29 2020 at 14:55)</a>:</h4>
<p>I feel like the only potential problem we could have is if we were to mark mutable references to these dangling pointers as <code>noalias</code></p>



<a name="208438280"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208438280" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208438280">(Aug 29 2020 at 15:06)</a>:</h4>
<p><span class="user-mention silent" data-user-id="123586">nagisa</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208437590">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> LLVM has to consider pointers that come out of thin air (i.e. <code>intptrcast</code>ed from some arbitrary non-zero integer) "valid", so "dangling" is not a problem I believe, and so <code>GEPi (inttoptr $align)</code> should also be fine.</p>
</blockquote>
<p>yes, that's what I said. the interesting question is, what about pointers that are not intrptrcasted, but come from some actual allocation, and that allocation has been free'd.</p>



<a name="208439137"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208439137" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208439137">(Aug 29 2020 at 15:26)</a>:</h4>
<p>aha, yeah that seems UB, GEPi requires it is used on a valid object. As an obvious optimisation compiler could do is have something that replaces gepis with <code>unreachable</code> if it knows the gepi is on an invalid object. I’m almost 100% sure such an optimisation would not have 0-size as a special case.</p>



<a name="208439181"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208439181" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208439181">(Aug 29 2020 at 15:26)</a>:</h4>
<blockquote>
<p>If the inbounds keyword is present, the result value of the getelementptr is a poison value if the base pointer is not an in bounds address of an allocated object</p>
</blockquote>
<p>looks like I'm wrong, you'd get some poison not ub</p>



<a name="208444195"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208444195" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208444195">(Aug 29 2020 at 17:16)</a>:</h4>
<p>yeah but poison is bad enough</p>



<a name="208444262"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208444262" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208444262">(Aug 29 2020 at 17:17)</a>:</h4>
<p><span class="user-mention" data-user-id="123586">@nagisa</span> I agree that such a pass is conceivable and legal under some interpretation of the LLVM rules. but it has some annoying consequences for ZST references in rust, and I am not convinced there's enough benefit here -- for example, everything alias-analysis-related that comes out of <code>inbounds</code> still remains valid if we say "inbounds-by-0 is always okay (except on the NULL ptr)".</p>



<a name="208444272"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208444272" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208444272">(Aug 29 2020 at 17:17)</a>:</h4>
<p>so basically I am saying this poison causes more trouble than it is worth. but unfortunately it is likely not something we can change.</p>



<a name="208459984"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208459984" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208459984">(Aug 29 2020 at 23:50)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208426103">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208387331">said</a>:</p>
<blockquote>
<p>Here's a thought: model ZST pointers as the same as integers (i.e. with the same provenance as what you would get by casting a pointer to an integer). They can't actually be dereferenced, or really anything else except casting to other types (since offsetting does nothing), so a simple integer model should be possible</p>
</blockquote>
<p>nono that would be an awful lot of complexity. having pointers with provenance cast to and from integers without is bad enough. <em>everything</em> based on provenance would suddenly have to rely on an analysis "is this a ZST ptr or not" (and with dynamically sized types or polymorphic MIR code you might not even know).</p>
</blockquote>
<p>Just to clarify: I was under the impression that LLVM doesn't deal with polymorphic rust code at all. My proposal is to treat ZST pointers the same way that integers are treated when lowering to LLVM. I don't think it adds any additional complexity around provenance beyond what ptr-to-int casts already deal with. At the rust / MIR level they can still be pointers and analysis can treat them as such, but because LLVM doesn't know about zero size allocations (and in any case I don't think we want to generate fake allocation code in the first place), there is no other appropriate pointer-like model for ZST pointers besides simple integers (or more accurately, <code>usize</code> values as opaque types with no operations).</p>



<a name="208471775"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208471775" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208471775">(Aug 30 2020 at 06:44)</a>:</h4>
<blockquote>
<p>I was under the impression that LLVM doesn't deal with polymorphic rust code at all. </p>
</blockquote>
<p>True. But we also do some optimizations on the MIR, pre-monomorphization, and we'd like to do more of that in the future.<br>
"optimziations" != "LLVM".</p>



<a name="208471784"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208471784" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208471784">(Aug 30 2020 at 06:45)</a>:</h4>
<p>and also, there's <code>&amp;dyn Trait</code> and <code>&amp;[i32]</code>, where you cannot tell during LLVM lowering whether it's a ZST or not</p>



<a name="208472525"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208472525" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208472525">(Aug 30 2020 at 07:10)</a>:</h4>
<p>I'm hoping that all optimizations except the LLVM lowered stuff can be taught that ZST pointers are pointers but have a different notion of "within bounds"</p>



<a name="208472546"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208472546" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208472546">(Aug 30 2020 at 07:11)</a>:</h4>
<p>The <code>&amp;dyn Trait</code> and <code>&amp;[i32]</code> examples are interesting. How are these represented in LLVM? I would guess the latter is a <code>(*const i32, usize)</code> pair. Does this suffer from mis-optimization in the zero case?</p>



<a name="208472836"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208472836" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208472836">(Aug 30 2020 at 07:21)</a>:</h4>
<p>they are pairs of pointers and metadata (where metadata is a vtable ptr or the length, respectively)</p>



<a name="208472846"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208472846" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208472846">(Aug 30 2020 at 07:21)</a>:</h4>
<p>and the problem isnt how to lower the pointers, the problem is how to lower the <em>operations</em> on them</p>



<a name="208472900"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208472900" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208472900">(Aug 30 2020 at 07:23)</a>:</h4>
<p>basically, we'd need to never do <code>getelementptr inbounds</code> with a zero offset, as we <em>might</em> be in a ZST when we do that. and we need to change the <code>offset</code> intrinsic to also avoid this -- the latter alone could kill this entire idea as the offset there can be dynamically determined and this is for hot loops, sow e certainly do not want a branch</p>



<a name="208473291"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208473291" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208473291">(Aug 30 2020 at 07:34)</a>:</h4>
<p>is there a <code>getelementptr outofbounds</code>?</p>



<a name="208473303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208473303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208473303">(Aug 30 2020 at 07:34)</a>:</h4>
<p>I can see how this might be a fatal problem without LLVM changes though</p>



<a name="208473363"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208473363" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208473363">(Aug 30 2020 at 07:36)</a>:</h4>
<p>Do you have a link to that LLVM mailing list conversation?</p>



<a name="208473774"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208473774" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208473774">(Aug 30 2020 at 07:52)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208473291">said</a>:</p>
<blockquote>
<p>is there a <code>getelementptr outofbounds</code>?</p>
</blockquote>
<p>there's plain <code>getelementptr</code> without "inbounds"</p>



<a name="208473783"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208473783" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208473783">(Aug 30 2020 at 07:52)</a>:</h4>
<p><code>getelementptr inbounds</code> corresponds to <a href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset">https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset</a>.<br>
<code>getelementptr</code> corresponds to <a href="https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.wrapping_offset">https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.wrapping_offset</a>.</p>



<a name="208473842"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208473842" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208473842">(Aug 30 2020 at 07:54)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208473363">said</a>:</p>
<blockquote>
<p>Do you have a link to that LLVM mailing list conversation?</p>
</blockquote>
<p>as usual mailman archives are horrible...<br>
here's my initial mail: <a href="https://lists.llvm.org/pipermail/llvm-dev/2019-February/130452.html">https://lists.llvm.org/pipermail/llvm-dev/2019-February/130452.html</a><br>
the first email of the March part of that thread: <a href="https://lists.llvm.org/pipermail/llvm-dev/2019-March/130831.html">https://lists.llvm.org/pipermail/llvm-dev/2019-March/130831.html</a><br>
first email of the april part: <a href="https://lists.llvm.org/pipermail/llvm-dev/2019-April/131693.html">https://lists.llvm.org/pipermail/llvm-dev/2019-April/131693.html</a><br>
and I think that's it</p>



<a name="208474449"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474449" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474449">(Aug 30 2020 at 08:15)</a>:</h4>
<p>Thanks, that was an interesting read. How feasible do you think it would be to only put the <code>inbounds</code> in when we can prove (on the rust side) that the pointer is not a ZST or the offset is not 0?</p>



<a name="208474479"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474479" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474479">(Aug 30 2020 at 08:16)</a>:</h4>
<p>it's sufficient to be able to prove that the offset is not 0</p>



<a name="208474500"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474500" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474500">(Aug 30 2020 at 08:16)</a>:</h4>
<p>well the first thing might be easier since usually the type is known</p>



<a name="208474501"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474501" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474501">(Aug 30 2020 at 08:16)</a>:</h4>
<p>and while this might be feasible for struct field accesses, I am not at all sure it is feasible for the <code>offset</code> intrinsic</p>



<a name="208474506"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474506" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474506">(Aug 30 2020 at 08:16)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208474500">said</a>:</p>
<blockquote>
<p>well the first thing might be easier since usually the type is known</p>
</blockquote>
<p>when the type is known, the field is also known and then we can just use that^^ I don't think looking at the type helps</p>



<a name="208474510"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474510" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474510">(Aug 30 2020 at 08:17)</a>:</h4>
<p>I mean if it is <code>&amp;x[n]</code> where <code>x: &amp;[T]</code> and <code>T</code> is not a zst</p>



<a name="208474557"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474557" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474557">(Aug 30 2020 at 08:18)</a>:</h4>
<p>oh, for indexing... right.</p>



<a name="208474559"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474559" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474559">(Aug 30 2020 at 08:18)</a>:</h4>
<p>I was thinking more of <code>ptr.field</code>.</p>



<a name="208474562"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474562" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474562">(Aug 30 2020 at 08:18)</a>:</h4>
<p>ah, a zst with zst fields?</p>



<a name="208474567"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474567" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474567">(Aug 30 2020 at 08:19)</a>:</h4>
<p>yes</p>



<a name="208474571"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474571" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474571">(Aug 30 2020 at 08:19)</a>:</h4>
<p>so I'm sure the basic <code>offset</code> intrinsic will not be able to prove this in general. How significant of a pessimization would it be to leave off the <code>inbounds</code> there?</p>



<a name="208474614"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474614" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474614">(Aug 30 2020 at 08:20)</a>:</h4>
<p>It's still just an addition, there is no branch being introduced</p>



<a name="208474621"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474621" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474621">(Aug 30 2020 at 08:20)</a>:</h4>
<p>my understanding is that it just gives LLVM less aliasing info to work with</p>



<a name="208474673"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474673" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474673">(Aug 30 2020 at 08:22)</a>:</h4>
<p>so the immediate effects aren't obvious, it will cause some optimization to not trigger in some cases</p>



<a name="208474680"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474680" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474680">(Aug 30 2020 at 08:22)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208474571">said</a>:</p>
<blockquote>
<p>so I'm sure the basic <code>offset</code> intrinsic will not be able to prove this in general. How significant of a pessimization would it be to leave off the <code>inbounds</code> there?</p>
</blockquote>
<p>I have no numbers. but the entire reason it exists (beyond <code>wrapping_offset</code>) is to have the <code>inbounds</code>.</p>



<a name="208474689"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474689" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474689">(Aug 30 2020 at 08:23)</a>:</h4>
<p>But do you think it is used often on types that are not provably ZST or non-ZST?</p>



<a name="208474732"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474732" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474732">(Aug 30 2020 at 08:24)</a>:</h4>
<p>You have to be working with unsized types to get into such a situation AFAICT</p>



<a name="208474735"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474735" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474735">(Aug 30 2020 at 08:24)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208474689">said</a>:</p>
<blockquote>
<p>But do you think it is used often on types that are not provably ZST or non-ZST?</p>
</blockquote>
<p>this is a raw ptr method</p>



<a name="208474736"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474736" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474736">(Aug 30 2020 at 08:24)</a>:</h4>
<p>you cannot use the types for anything</p>



<a name="208474748"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474748" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474748">(Aug 30 2020 at 08:25)</a>:</h4>
<p>you'd have to prove that the actual offset is not 0</p>



<a name="208474755"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474755" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474755">(Aug 30 2020 at 08:25)</a>:</h4>
<p>Maybe I'm misunderstanding the effect of the <code>offset</code> function. I thought it was the same as C's <code>&amp;x[n]</code></p>



<a name="208474802"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474802" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474802">(Aug 30 2020 at 08:26)</a>:</h4>
<p>kindof, yeah</p>



<a name="208474805"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474805" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474805">(Aug 30 2020 at 08:27)</a>:</h4>
<p>but if we want to say that offset-by-0 is okay on deallocated pointers, we have to cahnge behavior of all offset-by-0</p>



<a name="208474811"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474811" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474811">(Aug 30 2020 at 08:27)</a>:</h4>
<p>Double checking the signature, it has a <code>&lt;T&gt;</code>. My contention is that if <code>sizeof(T) != 0</code> then GEPi is okay</p>



<a name="208474813"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474813" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474813">(Aug 30 2020 at 08:27)</a>:</h4>
<p>we cannot rely on type information. this is used by unsafe code, including for actual ZST but after some type casts.</p>



<a name="208474874"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474874" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474874">(Aug 30 2020 at 08:29)</a>:</h4>
<p>so you are saying that <code>offset&lt;T&gt;(p, n)</code> is defined to have the same effect as <code>offset&lt;u8&gt;(p as *const u8, n * sizeof&lt;T&gt;())</code>?</p>



<a name="208474938"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474938" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474938">(Aug 30 2020 at 08:31)</a>:</h4>
<p>Is it also the same as <code>(p as usize) + n * sizeof&lt;T&gt;()</code> (in terms of runtime behavior / UB, not necessarily information as conveyed to LLVM)?</p>



<a name="208474987"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208474987" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208474987">(Aug 30 2020 at 08:33)</a>:</h4>
<p>The <a href="https://doc.rust-lang.org/std/intrinsics/fn.offset.html">doc</a> says:</p>
<blockquote>
<p>Both the starting and resulting pointer must be either in bounds or one byte past the end of an allocated object. If either pointer is out of bounds or arithmetic overflow occurs then any further use of the returned value will result in undefined behavior.</p>
</blockquote>
<p>which looks cribbed straight from LLVM. How is that return value modeled? Does Miri also have <code>poison</code>?</p>



<a name="208475039"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208475039" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208475039">(Aug 30 2020 at 08:34)</a>:</h4>
<p>oh right, miri doesn't like pointers</p>



<a name="208475062"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208475062" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208475062">(Aug 30 2020 at 08:35)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208474874">said</a>:</p>
<blockquote>
<p>so you are saying that <code>offset&lt;T&gt;(p, n)</code> is defined to have the same effect as <code>offset&lt;u8&gt;(p as *const u8, n * sizeof&lt;T&gt;())</code>?</p>
</blockquote>
<p>I think it would be really confusing if it didn't. and "confusing" is the last thing we want for unsafe APIs.</p>



<a name="208475063"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208475063" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208475063">(Aug 30 2020 at 08:35)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208474938">said</a>:</p>
<blockquote>
<p>Is it also the same as <code>(p as usize) + n * sizeof&lt;T&gt;()</code> (in terms of runtime behavior / UB, not necessarily information as conveyed to LLVM)?</p>
</blockquote>
<p>no, not at all. ineteger addition is very different from pointer arithmetic. (the same is true in C.)</p>



<a name="208475113"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208475113" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208475113">(Aug 30 2020 at 08:36)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208475039">said</a>:</p>
<blockquote>
<p>oh right, miri doesn't like pointers</p>
</blockquote>
<p>not sure what you mean. miri fully supports pointers.</p>



<a name="208475118"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208475118" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208475118">(Aug 30 2020 at 08:36)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208474987">said</a>:</p>
<blockquote>
<p>The <a href="https://doc.rust-lang.org/std/intrinsics/fn.offset.html">doc</a> says:</p>
<blockquote>
<p>Both the starting and resulting pointer must be either in bounds or one byte past the end of an allocated object. If either pointer is out of bounds or arithmetic overflow occurs then any further use of the returned value will result in undefined behavior.</p>
</blockquote>
<p>which looks cribbed straight from LLVM. How is that return value modeled? Does Miri also have <code>poison</code>?</p>
</blockquote>
<p>yes, this is basically just forwarding LLVM requirements -- except in Rust we say it is insta-UB to violate this condition. so we don't need poison for this.</p>



<a name="208475119"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208475119" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208475119">(Aug 30 2020 at 08:36)</a>:</h4>
<p>maybe I'm confusing it with const-eval</p>



<a name="208475122"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208475122" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208475122">(Aug 30 2020 at 08:36)</a>:</h4>
<p>that said, miri does have poison; it is called <code>Uninit</code>.</p>



<a name="208475194"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208475194" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208475194">(Aug 30 2020 at 08:39)</a>:</h4>
<p>Okay so to take a different tack, suppose there is a fictional zero-malloc dispensing valid ZST pointers at address 4. All valid ZSTs must point into a valid allocation, including that one. What are the issues with that model? I guess that's the closest to current reality</p>



<a name="208475289"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208475289" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208475289">(Aug 30 2020 at 08:42)</a>:</h4>
<p>One thing I can see is that the zero-malloc might dispense memory in the middle of another allocation (unlikely but possible if the ZST has large alignment). So you can get say <code>(4..20): &amp;mut [u8]</code> and <code>8: &amp;mut [u64; 0]</code> at the same time, which is bad</p>



<a name="208475447"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208475447" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208475447">(Aug 30 2020 at 08:48)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208475194">said</a>:</p>
<blockquote>
<p>Okay so to take a different tack, suppose there is a fictional zero-malloc dispensing valid ZST pointers at address 4. All valid ZSTs must point into a valid allocation, including that one. What are the issues with that model? I guess that's the closest to current reality</p>
</blockquote>
<p>kinda, yeah. LLVM doesn't assume it knows that <em>all</em> allocations exist, and allocations of size 0 are rather inconsequential. so they might just exist anywhere.</p>



<a name="208475448"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208475448" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208475448">(Aug 30 2020 at 08:48)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208475289">said</a>:</p>
<blockquote>
<p>One thing I can see is that the zero-malloc might dispense memory in the middle of another allocation (unlikely but possible if the ZST has large alignment). So you can get say <code>(4..20): &amp;mut [u8]</code> and <code>8: &amp;mut [u64; 0]</code> at the same time, which is bad</p>
</blockquote>
<p>indeed, I have been wondering about the same thing.</p>



<a name="208476451"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208476451" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208476451">(Aug 30 2020 at 09:22)</a>:</h4>
<p>Is there a maximum alignment? It doesn't seem too onerous to guarantee that non-ZST types must never be allocated (by a proper allocator) at addresses smaller than the largest alignment. At least on normal platforms that's certainly the case</p>



<a name="208477222"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208477222" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208477222">(Aug 30 2020 at 09:47)</a>:</h4>
<p>no I dont think there is a maximum alignment</p>



<a name="208477270"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208477270" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Peter Rabbit <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208477270">(Aug 30 2020 at 09:48)</a>:</h4>
<p>You can very easily have an alignment significantly higher than the page size, and there are a few open issues about them actually.</p>



<a name="208481223"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208481223" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208481223">(Aug 30 2020 at 11:43)</a>:</h4>
<p>I suspect that these requirements are close enough to plausible that it's actually possible to get miscompilation: use a very large regular allocation <code>x</code> that spans a power of 2 address, use <code>dangling()</code> to construct a ZST pointer <code>y</code> with the same address, and then pass both mutable pointers to a function (that assumes they are disjoint), and do something in the function to make it call GEPi 0 on the ZST (and hence assert validity of the address). Now LLVM will be able to prove that <code>x.begin() &lt; y &lt; x.end()</code> is false even though it is true at run time, so you can put some UB behind an if statement saying <code>!(x.begin() &lt; y &lt; x.end())</code> and boom, UB in safe code.</p>



<a name="208482145"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208482145" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208482145">(Aug 30 2020 at 12:06)</a>:</h4>
<p>alias assumptions are not used to optimize pointer comparisons, and indeed that would be wrong</p>



<a name="208482149"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208482149" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208482149">(Aug 30 2020 at 12:06)</a>:</h4>
<p>like, <code>&amp;mut ()</code> and <code>&amp;mut i32</code> can have the same value, if they point to the two fields of a <code>((), i32)</code>.</p>



<a name="208482699"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208482699" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208482699">(Aug 30 2020 at 12:22)</a>:</h4>
<p>True, but <em>strict</em> inequalities?</p>



<a name="208482712"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208482712" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208482712">(Aug 30 2020 at 12:22)</a>:</h4>
<p>I realize disjoint allocations can abut, but I don't think they can nest</p>



<a name="208482791"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208482791" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208482791">(Aug 30 2020 at 12:24)</a>:</h4>
<p>I tried to set up my test, and managed to get lucky enough to get malloc to give me an allocation spanning a power of two, namely 2^46, but I was not able to declare a ZST with that alignment:</p>
<div class="codehilite"><pre><span></span><code><span class="cp">#[repr(align(0x4000_0000_0000))]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">MyZST</span><span class="p">;</span><span class="w"></span>
<span class="c1">// invalid `repr(align)` attribute: larger than 2^29</span>
</code></pre></div>


<p>So I guess there are limits after all, at least in the attribute</p>



<a name="208483014"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208483014" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208483014">(Aug 30 2020 at 12:30)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208482699">said</a>:</p>
<blockquote>
<p>True, but <em>strict</em> inequalities?</p>
</blockquote>
<p>not sure how that makes any difference? non-aliasing pointers can still be <em>equal</em>.</p>



<a name="208483295"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208483295" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208483295">(Aug 30 2020 at 12:39)</a>:</h4>
<p>Success! It turns out that calling a function with mut pointers is not needed, even the box creation itself fails. This segfaults on my machine if and only if the final ZST box line is present (you may have to tweak the constants so that you don't run out of memory too early):</p>
<div class="codehilite"><pre><span></span><code><span class="cp">#[repr(align(0x2000_0000))]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">MyZST</span><span class="p">;</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">34</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">vec</span><span class="o">!</span><span class="p">[</span><span class="mi">0</span><span class="k">u8</span><span class="p">;</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)];</span><span class="w"></span>
<span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">()</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">n</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">29</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">break</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="nb">Box</span>::<span class="n">leak</span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">into_boxed_slice</span><span class="p">());</span><span class="w"></span>
<span class="w">    </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="n">MyZST</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="208483417"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208483417" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208483417">(Aug 30 2020 at 12:42)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208483014">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208482699">said</a>:</p>
<blockquote>
<p>True, but <em>strict</em> inequalities?</p>
</blockquote>
<p>not sure how that makes any difference? non-aliasing pointers can still be <em>equal</em>.</p>
</blockquote>
<p>Non aliasing pointers can not be in a strict nesting relation, <code>p1 &lt; q1 = q2 &lt; p2</code></p>



<a name="208483418"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208483418" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208483418">(Aug 30 2020 at 12:42)</a>:</h4>
<p>which is what this test sets up</p>



<a name="208483594"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208483594" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208483594">(Aug 30 2020 at 12:47)</a>:</h4>
<p>that segfault might just be one of the bugs related to large alignments not working properly though</p>



<a name="208483641"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208483641" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208483641">(Aug 30 2020 at 12:48)</a>:</h4>
<blockquote>
<p>Non aliasing pointers can not be in a strict nesting relation, p1 &lt; q1 = q2 &lt; p2</p>
</blockquote>
<p>I have no idea what you mean by this, there are 4 pointers here?</p>



<a name="208483645"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208483645" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208483645">(Aug 30 2020 at 12:48)</a>:</h4>
<p>LLVM will AFAIK not ever optimize <code>&lt;</code> or any other ptr comparison based on <code>noalias</code></p>



<a name="208483649"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208483649" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208483649">(Aug 30 2020 at 12:49)</a>:</h4>
<p>and I am pretty sure it would be wrong to do so even disregarding anything related to ZST</p>



<a name="208483697"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208483697" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208483697">(Aug 30 2020 at 12:49)</a>:</h4>
<p>note that <code>Box</code> and <code>&amp;mut</code> do not even have <code>noalias</code> currently for various reasons, so I doubt your test has anything to do with <code>noalias</code></p>



<a name="208483713"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208483713" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208483713">(Aug 30 2020 at 12:49)</a>:</h4>
<p>also, <code>&amp;</code> <em>does</em> have <code>noalias</code> (when there is no <code>UnsafeCell</code>). and clearly shared references can be in any kind of nesting relationship as they can freely alias. that's why I keep saying that <code>noalias</code> says absolutely nothing about pointer comparisons.</p>



<a name="208483861"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208483861" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208483861">(Aug 30 2020 at 12:53)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208483641">said</a>:</p>
<blockquote>
<blockquote>
<p>Non aliasing pointers can not be in a strict nesting relation, p1 &lt; q1 = q2 &lt; p2</p>
</blockquote>
<p>I have no idea what you mean by this, there are 4 pointers here?</p>
</blockquote>
<p>There are two allocation regions, in this case a u8 slice vs a ZST</p>



<a name="208484035"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484035" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484035">(Aug 30 2020 at 12:55)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208483594">said</a>:</p>
<blockquote>
<p>that segfault might just be one of the bugs related to large alignments not working properly though</p>
</blockquote>
<p>damn, you are right. the box alone causes the segfault. lowering the alignment causes it to work, although at alignment <code>0x40_0000</code> the stack overflows, which is not a good sign considering this is a ZST</p>



<a name="208484273"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484273" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484273">(Aug 30 2020 at 13:01)</a>:</h4>
<p>I think this is the issue you ran into: <a href="https://github.com/rust-lang/rust/issues/70143">https://github.com/rust-lang/rust/issues/70143</a></p>



<a name="208484327"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484327" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484327">(Aug 30 2020 at 13:02)</a>:</h4>
<p>Okay, we're back in business. This uses placement new to avoid aligning the stack, and shows the situation with overlapping mutable pointers:</p>
<div class="codehilite"><pre><span></span><code><span class="cp">#![feature(box_syntax, slice_ptr_range)]</span><span class="w"></span>
<span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">mem</span>::<span class="o">*</span><span class="p">;</span><span class="w"></span>

<span class="k">struct</span> <span class="nc">Field</span><span class="p">;</span><span class="w"></span>

<span class="cp">#[repr(align(0x2000_0000))]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">MyZST</span><span class="p">(</span><span class="n">Field</span><span class="p">);</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">34</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">vec</span><span class="o">!</span><span class="p">[</span><span class="mi">0</span><span class="k">u8</span><span class="p">;</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)];</span><span class="w"></span>
<span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">()</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">n</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">29</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">break</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="nb">Box</span>::<span class="n">leak</span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">into_boxed_slice</span><span class="p">());</span><span class="w"></span>
<span class="w">    </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">zst</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">box</span><span class="w"> </span><span class="n">MyZST</span><span class="p">(</span><span class="n">Field</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">foo</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">p</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">zst</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">big_alloc</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u8</span><span class="p">],</span><span class="w"> </span><span class="n">zst</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="n">MyZST</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">big_alloc</span><span class="p">.</span><span class="n">as_ptr_range</span><span class="p">();</span><span class="w"></span>

<span class="w">    </span><span class="n">println</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;{:x} &lt; {:x} &lt; {:x}&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">r</span><span class="p">.</span><span class="n">start</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">zst</span><span class="p">.</span><span class="mi">0</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">Field</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="n">r</span><span class="p">.</span><span class="n">end</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">usize</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="208484343"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484343" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484343">(Aug 30 2020 at 13:03)</a>:</h4>
<p>right, but what does it show? it's totally okay for ZST mutable refs to overlap with other mutable refs</p>



<a name="208484363"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484363" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484363">(Aug 30 2020 at 13:04)</a>:</h4>
<p>my only concern here -- the reason I said above that I thought about this before -- is an integer-cast ZST that happens to overlap with an actual allocation, and then that allocation going away. that could lead LLVM to conclude that the ZST dangles and that would be bad.</p>



<a name="208484414"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484414" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484414">(Aug 30 2020 at 13:04)</a>:</h4>
<p>that would not be allowed for any other type. I will have to play with LLVM optimizations to get it to do something interesting but I can make it GEPi 0 here and then LLVM will believe false things</p>



<a name="208484504"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484504" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484504">(Aug 30 2020 at 13:07)</a>:</h4>
<p>"for any other type"?</p>



<a name="208484511"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484511" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484511">(Aug 30 2020 at 13:07)</a>:</h4>
<p>what I said is not a weird exception, it falls out of the general rules of Stacked Borrows</p>



<a name="208484554"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484554" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484554">(Aug 30 2020 at 13:08)</a>:</h4>
<p>namely aliasing of mutable references is about whether the sets of locations covered by two references are disjoint</p>



<a name="208484561"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484561" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484561">(Aug 30 2020 at 13:08)</a>:</h4>
<p>a ZST reference covers no location, and since the empty set is disjoint from every set, it follows that it can never alias with any other reference</p>



<a name="208484584"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484584" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484584">(Aug 30 2020 at 13:09)</a>:</h4>
<p>I understand that, and from the viewpoint that regions are just sets of locations that makes perfect sense</p>



<a name="208484631"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484631" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484631">(Aug 30 2020 at 13:10)</a>:</h4>
<p>but another implementation of region disjointness is as inequality constraints on pairs, and I expect LLVM to be using this representation internally</p>



<a name="208484651"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484651" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484651">(Aug 30 2020 at 13:11)</a>:</h4>
<p>especially considering that they are mostly used to dealing with C where there are no zero size allocations</p>



<a name="208484768"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484768" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484768">(Aug 30 2020 at 13:14)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208484631">said</a>:</p>
<blockquote>
<p>but another implementation of region disjointness is as inequality constraints on pairs, and I expect LLVM to be using this representation internally</p>
</blockquote>
<p>I am pretty sure it is not using that representation</p>



<a name="208484770"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484770" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484770">(Aug 30 2020 at 13:14)</a>:</h4>
<p>To be more precise, the rule "<code>[a, b)</code> is disjoint from <code>[c, d)</code> if and only if <code>b &lt; c</code> or <code>d &lt; a</code>" is true only when <code>a &lt; b</code> and <code>c &lt; d</code>, which is always true for C allocations</p>



<a name="208484773"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484773" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484773">(Aug 30 2020 at 13:14)</a>:</h4>
<p>that would be very very incompatible with using <code>noalias</code> on shared references (that have no <code>UnsafeCell</code>)</p>



<a name="208484774"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484774" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484774">(Aug 30 2020 at 13:14)</a>:</h4>
<p>not sure if you saw above when I mentioned that</p>



<a name="208484782"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484782" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484782">(Aug 30 2020 at 13:14)</a>:</h4>
<p>for LVLM, aliasing is all about whether memory accesses can be reordered</p>



<a name="208484783"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484783" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484783">(Aug 30 2020 at 13:15)</a>:</h4>
<p>that's the only thing that actually matters</p>



<a name="208484793"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484793" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484793">(Aug 30 2020 at 13:15)</a>:</h4>
<p>(For C <code>restrict</code>, I have seen both claims -- that aliasing pointers are okay when they are left read-only, and that they are not okay.)</p>



<a name="208484928"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208484928" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208484928">(Aug 30 2020 at 13:18)</a>:</h4>
<p>I admit I don't have a good enough grasp on LLVM inner workings to determine how to exploit this possible bug. At this point it's mostly a spec mismatch, which might cause an exploitable problem and might not</p>



<a name="208485249"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485249" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485249">(Aug 30 2020 at 13:28)</a>:</h4>
<p>Hm, it looks like rust outsmarted me, and is using <code>bitcast</code> instead of GEP to extract ZST fields of a ZST</p>



<a name="208485338"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485338" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485338">(Aug 30 2020 at 13:30)</a>:</h4>
<p>it sometimes does that yes</p>



<a name="208485344"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485344" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485344">(Aug 30 2020 at 13:31)</a>:</h4>
<p>when the type from which you project is not actually compiled to a struct in LLVM</p>



<a name="208485353"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485353" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485353">(Aug 30 2020 at 13:31)</a>:</h4>
<p>make sure you have more than 2 non-ZST elements in your struct, that should sidestep this</p>



<a name="208485424"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485424" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485424">(Aug 30 2020 at 13:33)</a>:</h4>
<p>wait, if it has non-ZST elements then how is it supposed to be a ZST?</p>



<a name="208485577"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485577" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485577">(Aug 30 2020 at 13:36)</a>:</h4>
<p>oh I misread, I thought you were going for a ZST field of a non-ZST</p>



<a name="208485585"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485585" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485585">(Aug 30 2020 at 13:37)</a>:</h4>
<p>yeah... hm so maybe we already always do a bitcast instead of a GEP? Cc <span class="user-mention" data-user-id="119009">@eddyb</span></p>



<a name="208485603"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485603" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485603">(Aug 30 2020 at 13:37)</a>:</h4>
<p>what is the relevant context?</p>



<a name="208485654"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485654" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485654">(Aug 30 2020 at 13:38)</a>:</h4>
<p>when projecting to ZST fields of a ZST, do we always use bitcast? Or do we sometimes use <code>GEPi</code>?</p>



<a name="208485661"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485661" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485661">(Aug 30 2020 at 13:39)</a>:</h4>
<p>what's the offset?</p>



<a name="208485667"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485667" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485667">(Aug 30 2020 at 13:39)</a>:</h4>
<p>necessarily 0?</p>



<a name="208485674"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485674" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485674">(Aug 30 2020 at 13:39)</a>:</h4>
<p>how does GEPi with 0 offset meaningfully differ from <code>bitcast</code>?</p>



<a name="208485676"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485676" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485676">(Aug 30 2020 at 13:39)</a>:</h4>
<p>are we talking about the <code>inbounds</code> part?</p>



<a name="208485679"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485679" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485679">(Aug 30 2020 at 13:39)</a>:</h4>
<p>yes</p>



<a name="208485684"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485684" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485684">(Aug 30 2020 at 13:40)</a>:</h4>
<p>LLVM reads weird validity info from it</p>



<a name="208485685"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485685" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485685">(Aug 30 2020 at 13:40)</a>:</h4>
<p>you'd need a LLVM expert</p>



<a name="208485727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485727">(Aug 30 2020 at 13:40)</a>:</h4>
<p>cc <span class="user-mention" data-user-id="123586">@nagisa</span> <span class="user-mention" data-user-id="133224">@Nikita Popov</span></p>



<a name="208485740"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485740" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485740">(Aug 30 2020 at 13:41)</a>:</h4>
<p>using <code>bitcast</code> avoids the silliness around <code>GEP</code> requiring a struct type, but maybe we can just use a noop <code>GEPi</code> followed by a bitcast?</p>



<a name="208485741"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485741" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485741">(Aug 30 2020 at 13:41)</a>:</h4>
<p>I think we covered the LLVM side -- most people agree LangRef says it differs</p>



<a name="208485750"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485750" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485750">(Aug 30 2020 at 13:41)</a>:</h4>
<p>the question is, does <del>LLVM</del> Rust ever emit a <code>GEPi 0</code> on a ZST ref as part of field accesses?</p>



<a name="208485799"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485799" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485799">(Aug 30 2020 at 13:42)</a>:</h4>
<p><del>why would LLVM emit LLVM instructions?</del></p>



<a name="208485803"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485803" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485803">(Aug 30 2020 at 13:42)</a>:</h4>
<p>(oops, I meant rustc)</p>



<a name="208485804"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485804" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485804">(Aug 30 2020 at 13:42)</a>:</h4>
<p>to be fair, it does emit this elsewhere, in particular for <code>ptr::offset</code>, so even if we dont do it for fields it doesn't really help that much</p>



<a name="208485807"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485807" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485807">(Aug 30 2020 at 13:42)</a>:</h4>
<p>yeah you'll easily hit this for array accesses</p>



<a name="208485813"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485813" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485813">(Aug 30 2020 at 13:43)</a>:</h4>
<p>is there a reason we <em>shouldn't</em> set <code>inbounds</code> when accessing something inside a ZST?</p>



<a name="208485818"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485818" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485818">(Aug 30 2020 at 13:43)</a>:</h4>
<p>(i.e. not any ZST field, but specifically a ZST field of a ZST type)</p>



<a name="208485828"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485828" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485828">(Aug 30 2020 at 13:43)</a>:</h4>
<p>we can probably avoid it if it matters, even for <code>ptr::offset</code>, with the right checks</p>



<a name="208485874"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485874" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485874">(Aug 30 2020 at 13:44)</a>:</h4>
<p>the problem is that ZSTs were never allocated</p>



<a name="208485883"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485883" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485883">(Aug 30 2020 at 13:44)</a>:</h4>
<blockquote>
<p>If the inbounds keyword is present, the result value of the getelementptr is a poison value if the base pointer is not an in bounds address of an allocated object, or if any of the addresses that would be formed by successive addition of the offsets implied by the indices to the base address with infinitely precise signed arithmetic are not an in bounds address of that allocated object.</p>
</blockquote>



<a name="208485887"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485887" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485887">(Aug 30 2020 at 13:45)</a>:</h4>
<p>and in particular the standard "allocator" for ZSTs can place them inside other allocations</p>



<a name="208485890"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485890" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485890">(Aug 30 2020 at 13:45)</a>:</h4>
<p>okay I see, I didn't know it had requirements on the base pointer, only on additions</p>



<a name="208485898"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485898" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485898">(Aug 30 2020 at 13:45)</a>:</h4>
<p>doesn't LLVM replace noop GEPs with <code>bitcast</code>s ASAP?</p>



<a name="208485942"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485942" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nikita Popov <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485942">(Aug 30 2020 at 13:46)</a>:</h4>
<p>LLVM tends to replace bitcasts with zero index GEPs.</p>



<a name="208485950"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485950" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485950">(Aug 30 2020 at 13:46)</a>:</h4>
<p>the other way around? wow</p>



<a name="208485957"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485957" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485957">(Aug 30 2020 at 13:46)</a>:</h4>
<p>Okay, here's the latest version of the test</p>
<div class="codehilite"><pre><span></span><code><span class="cp">#![feature(box_syntax, slice_ptr_range)]</span><span class="w"></span>

<span class="k">struct</span> <span class="nc">Field</span><span class="p">;</span><span class="w"></span>

<span class="cp">#[repr(align(0x2000_0000))]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">MyZST</span><span class="p">(</span><span class="n">Field</span><span class="p">,</span><span class="w"> </span><span class="n">Field</span><span class="p">);</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">34</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">vec</span><span class="o">!</span><span class="p">[</span><span class="mi">0</span><span class="k">u8</span><span class="p">;</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)];</span><span class="w"></span>
<span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">()</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">n</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">29</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">break</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="nb">Box</span>::<span class="n">leak</span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">into_boxed_slice</span><span class="p">());</span><span class="w"></span>
<span class="w">    </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">zst</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">box</span><span class="w"> </span><span class="n">MyZST</span><span class="p">(</span><span class="n">Field</span><span class="p">,</span><span class="w"> </span><span class="n">Field</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">diff</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="o">&amp;*</span><span class="n">zst</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">MyZST</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">()</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">usize</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">foo</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">p</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">zst</span><span class="p">,</span><span class="w"> </span><span class="n">diff</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">big_alloc</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u8</span><span class="p">],</span><span class="w"> </span><span class="n">zst</span>: <span class="kp">&amp;</span><span class="nc">MyZST</span><span class="p">,</span><span class="w"> </span><span class="n">diff</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">zst2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">zst</span><span class="p">.</span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">not_zst</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">big_alloc</span><span class="p">[</span><span class="n">diff</span><span class="p">];</span><span class="w"></span>
<span class="w">    </span><span class="n">assert</span><span class="o">!</span><span class="p">((</span><span class="n">zst2</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">Field</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="p">(</span><span class="n">not_zst</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="kt">u8</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">usize</span><span class="p">));</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>


<p>I suspect that LLVM will be able to prove that the assertion is false</p>



<a name="208485967"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208485967" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208485967">(Aug 30 2020 at 13:47)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> I mean, as far as ZSTs are concerned, there's "objects" between every consecutive pair of bytes (except at address <code>0</code> for null reasons), but I'm not sure LLVM agrees</p>



<a name="208486048"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486048" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486048">(Aug 30 2020 at 13:49)</a>:</h4>
<p><span class="user-mention" data-user-id="133224">@Nikita Popov</span> but those GEPs are not <code>inbounds</code>, right?</p>



<a name="208486108"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486108" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486108">(Aug 30 2020 at 13:51)</a>:</h4>
<p>I still haven't figured out how to force a GEPi yet though. Since <code>not_zst</code> is (validly, <code>inbounds</code>) derived from a valid allocation, and <code>zst</code> is marked <code>noalias</code>, LLVM should be able to prove that they are not equal</p>



<a name="208486129"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486129" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nikita Popov <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486129">(Aug 30 2020 at 13:51)</a>:</h4>
<p><span class="user-mention" data-user-id="119009">@eddyb</span> <a href="https://github.com/llvm/llvm-project/blob/11cf6346fd49a54cf1f0a8fbf5dee0dab0f4f217/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp#L2543-L2573">https://github.com/llvm/llvm-project/blob/11cf6346fd49a54cf1f0a8fbf5dee0dab0f4f217/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp#L2543-L2573</a></p>



<a name="208486179"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486179" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nikita Popov <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486179">(Aug 30 2020 at 13:52)</a>:</h4>
<p>So yes, it's a non-inbounds gep unless we know it's derefable (or null).</p>



<a name="208486184"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486184" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486184">(Aug 30 2020 at 13:52)</a>:</h4>
<p>okay that makes sense</p>



<a name="208486192"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486192" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486192">(Aug 30 2020 at 13:53)</a>:</h4>
<p>not too happy with it but it's not like it's wrong, and given how much of LLVM relies too much on seeing GEPs, it probably makes sense</p>



<a name="208486239"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486239" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486239">(Aug 30 2020 at 13:54)</a>:</h4>
<p>but that means that ZST pointers qualify, right?</p>



<a name="208486250"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486250" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486250">(Aug 30 2020 at 13:54)</a>:</h4>
<p>no, a <code>&amp;Zst</code> argument shouldn't be marked <code>dereferenceable</code></p>



<a name="208486309"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486309" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486309">(Aug 30 2020 at 13:56)</a>:</h4>
<p><code>%MyZST* noalias nonnull readonly align 536870912 %zst</code></p>



<a name="208486311"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486311" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486311">(Aug 30 2020 at 13:56)</a>:</h4>
<p>yeah it's not</p>



<a name="208486312"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486312" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486312">(Aug 30 2020 at 13:56)</a>:</h4>
<p>aha</p>



<a name="208486315"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486315" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486315">(Aug 30 2020 at 13:56)</a>:</h4>
<p>maybe it should also not be <code>noalias</code>?</p>



<a name="208486319"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486319" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486319">(Aug 30 2020 at 13:56)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> anyway, like <span class="user-mention" data-user-id="120791">@RalfJ</span> said, try <code>ptr::offset</code></p>



<a name="208486327"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486327" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486327">(Aug 30 2020 at 13:57)</a>:</h4>
<p>or just indexing <code>array: [Zst; 1]</code> with <code>&amp;array[0]</code></p>



<a name="208486345"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486345" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486345">(Aug 30 2020 at 13:57)</a>:</h4>
<p>(if that gets folded into a field-like access, use a variable that happens to be <code>0</code>, heh, or pass it as an argument, etc.)</p>



<a name="208486394"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486394" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486394">(Aug 30 2020 at 13:58)</a>:</h4>
<p>wait I have this right here, I can test that</p>



<a name="208486396"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486396" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486396">(Aug 30 2020 at 13:58)</a>:</h4>
<p>bingo</p>



<a name="208486398"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486398" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486398">(Aug 30 2020 at 13:58)</a>:</h4>
<p>the array worked</p>



<a name="208486404"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486404" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486404">(Aug 30 2020 at 13:59)</a>:</h4>
<p><a href="https://godbolt.org/z/MW86oc">https://godbolt.org/z/MW86oc</a></p>



<a name="208486419"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486419" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486419">(Aug 30 2020 at 13:59)</a>:</h4>
<p>it doesn't optimize <code>foo</code> itself, nor <code>main</code> with <code>foo</code> inlined in it</p>



<a name="208486473"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486473" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486473">(Aug 30 2020 at 14:00)</a>:</h4>
<p>checking with <code>fn main</code> and <code>-O</code> removed, it does emit <code>inbounds</code> for the ZST at first</p>



<a name="208486484"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486484" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486484">(Aug 30 2020 at 14:01)</a>:</h4>
<p>but then it gets optimized into something simpler. and it doesn't make assumptions based on <code>noalias</code></p>



<a name="208486496"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486496" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486496">(Aug 30 2020 at 14:01)</a>:</h4>
<p>I highly suspect <code>noalias</code> only matters for accesses, not <code>inbounds</code>, but I have no easy way to prove that. and we can just remove either or both <em>shrug</em></p>



<a name="208486543"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486543" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486543">(Aug 30 2020 at 14:02)</a>:</h4>
<p>I was using two <code>&amp;mut</code>'s initially but that didn't get the <code>noalias</code></p>



<a name="208486554"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486554" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486554">(Aug 30 2020 at 14:02)</a>:</h4>
<p>you need a flag IIRC?</p>



<a name="208486558"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486558" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486558">(Aug 30 2020 at 14:02)</a>:</h4>
<p>because of another LLVM bug?</p>



<a name="208486571"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486571" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486571">(Aug 30 2020 at 14:03)</a>:</h4>
<p><code>-Z mutable-noalias</code></p>



<a name="208486576"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208486576" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208486576">(Aug 30 2020 at 14:03)</a>:</h4>
<p>doesn't really change the result though <a href="https://godbolt.org/z/Kea8e8">https://godbolt.org/z/Kea8e8</a></p>



<a name="208487411"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208487411" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208487411">(Aug 30 2020 at 14:25)</a>:</h4>
<p><span class="user-mention" data-user-id="119009">@eddyb</span>  the original question was, what do we have to require for things like <code>slice::from_raw_parts</code>, for empty slices -- or <code>Box::from_raw</code> for ZST? With these <code>GEPi</code> we have to distinguish between <code>Box::&lt;()&gt;::from_raw(4usize as _)</code>, which is fine, and <code>Box::from_raw</code> on a pointer to a memory allocation that has been freed (which is not fine).</p>



<a name="208487418"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208487418" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208487418">(Aug 30 2020 at 14:25)</a>:</h4>
<p>That distinction comes as quite the surprise to most (and in fact so far we fail to properly document it in the <code>ptr</code> module)</p>



<a name="208487487"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208487487" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208487487">(Aug 30 2020 at 14:26)</a>:</h4>
<p>I would require nothing for ZSTs and fix the impl to not tell LLVM lies in those cases, but that's just personal preference</p>



<a name="208487507"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208487507" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208487507">(Aug 30 2020 at 14:27)</a>:</h4>
<p>thankfully <code>size_of::&lt;T&gt;() == 0</code> is free in many cases, but I would be worried about <code>ptr::offset(p, dynamically_zero)</code> on a <code>*mut NotZST</code> that happens to be used as a ZST pointer later</p>



<a name="208487561"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208487561" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208487561">(Aug 30 2020 at 14:28)</a>:</h4>
<blockquote>
<p>but I would be worried about ptr::offset(p, dynamically_zero) on a *mut NotZST that happens to be used as a ZST pointer later</p>
</blockquote>
<p>exactly that is the case I am also worried about</p>



<a name="208487582"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208487582" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208487582">(Aug 30 2020 at 14:29)</a>:</h4>
<p><span class="user-mention silent" data-user-id="119009">eddyb</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208487487">said</a>:</p>
<blockquote>
<p>I would require nothing for ZSTs and fix the impl to not tell LLVM lies in those cases, but that's just personal preference</p>
</blockquote>
<p>if we can make that happen that would be best, yes. (or else convince LLVM to guarantee that <code>GEPi</code>-by-0 is always okay, but that seems unlikely.)<br>
it's just not clear if we can get there -- and it seems a bit fragile, every single GEPi we emit anywhere must be carefully scrutinized.</p>



<a name="208487700"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208487700" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208487700">(Aug 30 2020 at 14:33)</a>:</h4>
<p>unfortunately <code>offset(i)</code> doesn't work on a ZST type</p>



<a name="208487703"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208487703" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nikita Popov <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208487703">(Aug 30 2020 at 14:33)</a>:</h4>
<blockquote>
<p>and Box::from_raw on a pointer to a memory allocation that has been freed (which is not fine).</p>
</blockquote>
<p>As in, the ZST address coincides with that pointer, or is actually created from it?</p>



<a name="208487881"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208487881" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208487881">(Aug 30 2020 at 14:37)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133224">Nikita Popov</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208487703">said</a>:</p>
<blockquote>
<blockquote>
<p>and Box::from_raw on a pointer to a memory allocation that has been freed (which is not fine).</p>
</blockquote>
<p>As in, the ZST address coincides with that pointer, or is actually created from it?</p>
</blockquote>
<p>has actually been created from it</p>



<a name="208487896"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208487896" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nikita Popov <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208487896">(Aug 30 2020 at 14:37)</a>:</h4>
<p>Why would that be legal?</p>



<a name="208487906"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208487906" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208487906">(Aug 30 2020 at 14:37)</a>:</h4>
<p>why wouldnt it? "any non-null aligned ptr is a valid ZST reference" is an easy and sensible principle</p>



<a name="208487913"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208487913" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208487913">(Aug 30 2020 at 14:38)</a>:</h4>
<p>(the "coincides" part is something I am worried about even if we tell people that their ZST pointers must "come from" constant integers or actual live references)</p>



<a name="208487989"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208487989" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208487989">(Aug 30 2020 at 14:39)</a>:</h4>
<p>a formal semantics of GEPi, such <a href="https://people.mpi-sws.org/~jung/twinsem/twinsem.pdf">as this one</a>, <em>already</em> has to work with "deferred inbounds checks", as that is the only way to make GEPi pure and not depend on current memory. So I have a hard time imagining useful optimizations that would be broken by this. but I also don't know what many optimizations so this does not mean all too much. ;)</p>



<a name="208488070"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208488070" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nikita Popov <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208488070">(Aug 30 2020 at 14:41)</a>:</h4>
<p>Well, you can always put up a review on phab that changes the langref wording and see what people have to say about it :)</p>



<a name="208488080"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208488080" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nikita Popov <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208488080">(Aug 30 2020 at 14:41)</a>:</h4>
<p>I imagine the primary appeal of the current spec is that it tells you unconditionally that the gep base is a valid object. You wouldn't get that with a zero offset exception.</p>



<a name="208488138"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208488138" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208488138">(Aug 30 2020 at 14:42)</a>:</h4>
<p>Okay, finally a GEPi: <a href="https://godbolt.org/z/14b934">https://godbolt.org/z/14b934</a></p>



<a name="208488143"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208488143" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208488143">(Aug 30 2020 at 14:43)</a>:</h4>
<p>still not getting any interesting LLVM optimizations</p>



<a name="208488283"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208488283" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nikita Popov <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208488283">(Aug 30 2020 at 14:46)</a>:</h4>
<p>Anyway, memory model is very much not my strong suit. Possibly it would be enough to say that "if the gep base address points to a valid object, then the gep result also points into the same object" or so, to allow all useful optimizations.</p>



<a name="208488301"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208488301" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nikita Popov <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208488301">(Aug 30 2020 at 14:47)</a>:</h4>
<p>At least I imagine that the main thing we really care about is that gep doesn't jump between objects.</p>



<a name="208488358"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208488358" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208488358">(Aug 30 2020 at 14:48)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133224">Nikita Popov</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208488080">said</a>:</p>
<blockquote>
<p>I imagine the primary appeal of the current spec is that it tells you unconditionally that the gep base is a valid object. You wouldn't get that with a zero offset exception.</p>
</blockquote>
<p>well, but <code>0x4</code> is allowed as a base for offset 0</p>



<a name="208488367"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208488367" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208488367">(Aug 30 2020 at 14:48)</a>:</h4>
<p>not sure in which useful sense that is a "valid object"</p>



<a name="208488387"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208488387" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208488387">(Aug 30 2020 at 14:49)</a>:</h4>
<p>for ZST pointers they just don't need to be valid</p>



<a name="208488391"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208488391" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208488391">(Aug 30 2020 at 14:49)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133224">Nikita Popov</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208488301">said</a>:</p>
<blockquote>
<p>At least I imagine that the main thing we really care about is that gep doesn't jump between objects.</p>
</blockquote>
<p>yeah that is my thinking to. which is why I feel like an exception for the case of offset 0 would make a lot of sense</p>



<a name="208488397"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208488397" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208488397">(Aug 30 2020 at 14:49)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133224">Nikita Popov</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Box's.20Memory.20layout.20for.20ZSTs/near/208488070">said</a>:</p>
<blockquote>
<p>Well, you can always put up a review on phab that changes the langref wording and see what people have to say about it :)</p>
</blockquote>
<p>I have no idea how to ensure that optimizations conform to this stronger spec though^^</p>



<a name="208488398"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208488398" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208488398">(Aug 30 2020 at 14:49)</a>:</h4>
<p>at least in the sense of not dereferenceable</p>



<a name="208493438"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/208493438" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#208493438">(Aug 30 2020 at 16:46)</a>:</h4>
<p>Wow 180 messages, I didn't think it will start such a big discussion <span aria-label="sweat smile" class="emoji emoji-1f605" role="img" title="sweat smile">:sweat_smile:</span></p>



<a name="213009615"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/213009615" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#213009615">(Oct 12 2020 at 08:18)</a>:</h4>
<p>I finally opened a PR for clarifying the docs: <a href="https://github.com/rust-lang/rust/pull/77844">https://github.com/rust-lang/rust/pull/77844</a></p>



<a name="213010354"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/213010354" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#213010354">(Oct 12 2020 at 08:27)</a>:</h4>
<p>Great, i had a boxed zst issue just today actually.</p>



<a name="213052459"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box%27s%20Memory%20layout%20for%20ZSTs/near/213052459" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Box&#x27;s.20Memory.20layout.20for.20ZSTs.html#213052459">(Oct 12 2020 at 15:24)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> thanks :)</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>